package com.validate.controller;

import com.validate.data.User;
import org.hibernate.validator.constraints.Range;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.IOException;

@RestController
@RequestMapping("/validate")
public class ValidateController {
    @PostMapping("/user/out")
    public String validate(@Validated @RequestBody User user, BindingResult bindingResult) {
        if (bindingResult != null) {
            String message = "";
            for (ObjectError error : bindingResult.getAllErrors()) {
                FieldError e = (FieldError) error;
                System.out.println(e.getField() + " - " + e.getDefaultMessage());
                message += message + e.getField() + " - " + e.getDefaultMessage() + ";\n";
            }
            //如果需要捕获异常，需要手动抛出，否则程序将继续执行
            throw new ConstraintViolationException(message, null);
        }
        return null;
    }

    @PostMapping("/user/handle")
    public String validateAndHandle(@Validated @RequestBody User user) {
        //没有使用BindingResult接收错误信息会自动抛出 MethodArgumentNotValidException 异常
        return null;
    }

    @GetMapping("/param")
    public String validateParam(String name, Integer age) {
        return testMethodValidate(name, age);
    }

    // 好像方法和方法参数验证不生效
    @NotNull(message = "方法返回值不能为空")
    private String testMethodValidate(
            @NotBlank String name,
            @Range(min = 0, max = 150) Integer age) {
        return null;
    }

    @ExceptionHandler({
            ConstraintViolationException.class,
            MethodArgumentNotValidException.class,
            ServletRequestBindingException.class,
            BindException.class
    })
    public String handleException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
        try {
            if (e instanceof ConstraintViolationException
                    || e instanceof MethodArgumentNotValidException
                    || e instanceof ServletRequestBindingException
                    || e instanceof BindException) {
                response.sendError(HttpStatus.BAD_REQUEST.value(), "===参数校验失败！");
            }
        } catch (IOException exception) {
            System.out.println(exception.getMessage());
        }
        return null;
    }
}
